<?php
namespace App\Console\Commands;

use Illuminate\Console\Command;
use DB;
use Illuminate\Support\Facades\Config;

class SyncPlayerInfo extends Command{
    
    // 0: 不限制登录时间，1：一天内的， n 天之内的；
    const DAY = 0;
    
    const FIELD_SYNC = 'account,playerId,name,udid,area,level,heroId,vip,title,gold,diamond,goldRevive,diamondRevive,loginTime,onlineTime,lastLoginTime,createTime';

    const MAIN_DB = 'mysql_bgsi';
    
    const FIELD_KEY = 'account,area,playerId';

    const EFFECT_ROW = 500;

    protected $signature = 'player:sync';

    protected $description = '玩家信息同步';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle(){
        set_time_limit(0);
        $this->sync();
    }

    public function sync(){
        $connects = DB::connection('mysql')->table('game_db_conf')->where('status', 1)->where('deleted_at', 0)->get()->map(function($v){return (array)$v;})->toArray();


        foreach ($connects as $conn) {
            
            $conn = $this->_orgConn($conn);
            \Config::set('database.connections.sync', $conn);
            
            var_dump(Config::get('database.connections.sync'));
            $this->logic('sync');
        }
    }

    protected function logic($conn){
        $res = $this->from($conn);
        if (empty($res)) { 
            return [];
        }
        
        $fromRes = $this->from($conn);
        
        $logic = 1;
        $insertData = [];
        $count = count($res);
        foreach ($res as $item) {

            $insertData[] = $item;
            $this->delete($item);

            // 执行一次批量插入 500次循环 或者 是最大上线，是不会到500的情况
            if ($logic % self::EFFECT_ROW == 0 || $count == $logic) {
                echo "sync one time line {$logic}";
                $this->insert($insertData);
                unset($insertData);
                usleep(2000);
            }
            
            $logic++;
        }
        var_dump($count);
    }


    protected function from($connect){
        $day = self::DAY;
        $curr = $day ?strtotime("-{$day} day") : 0;
        $curr = date('Y-m-d 00:00:00', $curr);
        $op = DB::connection($connect)->table('player_info')->where('lastLoginTime', '>=', $curr);
        $result = $op->get(explode(',',self::FIELD_SYNC));
        $sql = $op->toSql();
            
        $res = [];
        $flds = explode(',', self::FIELD_SYNC);
        foreach ($result as $obj) {

            $item = [];
            foreach($flds as $attr){
                $item[$attr] = $obj->{$attr};
            }
            $pk = $this->getKey($item);
            $res[$pk] = $item;
            
        }
        echo $curr . " 同步记录数" .count($res);
        var_dump($sql);
        return $res;
    }

    // 判断的主键
    protected function getKey($item = [], $fld_key = self::FIELD_KEY){
        $pk = '';
        $pk_arr = [];

        $fld_key = explode(',', $fld_key);
        foreach ($fld_key as $attr) {
            $pk_arr[] = $item[$attr];
        }
        
        $pk = join('-', $pk_arr);
        return $pk;
    }

    protected function insert(array $data){
        $op = DB::connection(self::MAIN_DB)->table('player_info');
        $op->insert($data);
    }
    
    protected function update(array $data){
        $op = $this->centerDb($data);
        
        $op->update($data);
    }

    protected function delete(array $data){
        $op = $this->centerDb($data);
        $op->delete();
    }

    protected function findOne(array $data){
        $op = $this->centerDb($data);
        $one = $op->first();

        return $one;
    }

    protected function centerDb(array $data){
        $fld_key = explode(',', self::FIELD_KEY);

        $op = DB::connection(self::MAIN_DB)->table('player_info');
        foreach ($fld_key as $attr) {
            $op->where($attr, $data[$attr]);
        }

        return $op;
    }

    protected function _orgConn(array $conn){
        $rtn = [];
        $flds = ['host', 'port', 'database', 'username', 'password', 'charset', 'driver', 'collation', 'prefix', 'strict', 'engine']; //, 'unix_socket'];
        foreach ($flds as $attr) {
            $rtn[$attr] = $conn[$attr];
        }
        return $rtn;
    }
}

